<template>
  <div class="org-tree-container">
    <div class="search-box">
      <el-input v-model="searchKeyword" clearable placeholder="搜索部门" prefix-icon="Search" @input="handleSearchInput" />
    </div>
    <div v-loading="loading" class="tree-content">
      <el-tree
        ref="treeRef"
        class="filter-tree"
        :data="isSearchMode ? searchResults : rootNodes"
        :filter-node-method="filterNode"
        highlight-current
        lazy
        :load="loadData"
        node-key="id"
        :props="defaultProps"
        @node-click="handleNodeClick"
      >
        <template #default="{ node, data }">
          <div class="tree-node">
            <el-icon v-if="data.isExternal" class="external-icon"><avatar /></el-icon>
            <el-icon v-else-if="node.expanded"><folder-opened /></el-icon>
            <el-icon v-else><folder /></el-icon>
            <span class="node-label">{{ node.label }}</span>
          </div>
        </template>
      </el-tree>
    </div>
    <div class="tree-footer">
      <el-button link @click="handleRefresh">
        <refresh-right class="refresh-icon" />
        刷新
      </el-button>
    </div>
  </div>
</template>

<script setup lang="ts">
import { Avatar, Folder, FolderOpened, RefreshRight } from '@element-plus/icons-vue'
import { ElMessage } from 'element-plus'
import { nextTick, onMounted, ref, watch } from 'vue'
import { usePersonSelector } from '../composables/usePersonSelector'

const props = defineProps<{
  modelValue: string
}>()

const emit = defineEmits(['update:modelValue', 'node-click', 'refresh', 'load-start', 'load-end'])

// 使用通用的数据获取方法
const { loadDepartmentChildren, searchDepartments } = usePersonSelector()

// 状态变量
const treeRef = ref<any>(null)
const loading = ref(false)
const expandedKeys = ref<string[]>([])
const searchTimeout = ref<number | null>(null)
const searchKeyword = ref('')
const currentNodeId = ref('')
const searchResults = ref<any[]>([])
const isSearchMode = ref(false)
const rootNodes = ref<any[]>([])

// 树形控件配置
const defaultProps = {
  children: 'children',
  label: 'label',
  isLeaf: 'isLeaf',
}

// 初始化加载根节点
const loadRootNodes = async () => {
  loading.value = true
  emit('load-start')
  try {
    const nodes = await loadDepartmentChildren(null)
    console.log('初始加载根节点:', nodes)

    if (Array.isArray(nodes) && nodes.length > 0) {
      rootNodes.value = nodes.map((node) => ({
        ...node,
        // 确保根节点不被视为叶子节点
        isLeaf: false,
        hasChildren: true,
      }))
    } else {
      rootNodes.value = []
      console.warn('根节点数据加载不完整或为空')
    }
  } catch (error) {
    console.error('初始加载根节点失败:', error)
    rootNodes.value = []
  } finally {
    loading.value = false
    emit('load-end')
  }
}

// 加载节点数据 - 使用共享方法
const loadData = async (node: any, resolve: (data: any[]) => void) => {
  // 如果是根节点且已经有数据，直接使用已有数据
  if (node.level === 0 && rootNodes.value.length > 0) {
    console.log('使用已加载的根节点数据')
    resolve(rootNodes.value)
    return
  }

  emit('load-start')
  loading.value = true

  try {
    let nodes: any[] = []

    if (node.level === 0) {
      // 加载根节点
      nodes = await loadDepartmentChildren(null)
      console.log(nodes)

      // 确保数据已完全加载
      if (Array.isArray(nodes) && nodes.length > 0) {
        // 数据加载成功，可以安全地继续
        console.log('根节点数据加载成功:', nodes.length)
      } else {
        console.warn('根节点数据加载不完整或为空')
      }
    } else {
      // 加载子部门
      nodes = await loadDepartmentChildren(node.data.id)

      // 如果没有子节点，标记父节点为叶子节点
      if (nodes.length === 0) {
        node.data.isLeaf = true
      }
    }

    // 确保在resolve前数据已准备就绪
    setTimeout(() => {
      resolve(nodes)
      loading.value = false
      emit('load-end')
    }, 100)
  } catch (error) {
    console.error('加载部门失败', error)
    ElMessage.error('加载部门失败')
    resolve([])
    loading.value = false
    emit('load-end')
  }
}

// 处理节点点击事件
const handleNodeClick = (data: any) => {
  currentNodeId.value = data.id
  emit('update:modelValue', data.id)
  emit('node-click', data)
}

// 过滤节点方法（保留，但搜索模式下不再使用）
const filterNode = (value: string, data: any) => {
  if (!value) return true
  return data.label.toLowerCase().includes(value.toLowerCase())
}

// 搜索处理 - 使用共享方法
const handleSearchInput = (value: string) => {
  if (searchTimeout.value) {
    clearTimeout(searchTimeout.value)
  }

  searchTimeout.value = window.setTimeout(async () => {
    if (value.trim() === '') {
      // 清空搜索时恢复普通模式
      isSearchMode.value = false
      searchResults.value = []
      return
    }

    isSearchMode.value = true
    loading.value = true
    emit('load-start')

    try {
      // 使用共享方法搜索部门
      const results = await searchDepartments(value)
      searchResults.value = results
    } catch (error) {
      console.error('搜索部门失败', error)
      ElMessage.error('搜索部门失败')
      searchResults.value = []
    } finally {
      loading.value = false
      emit('load-end')
    }
  }, 300) as unknown as number
}

// 刷新树
const handleRefresh = () => {
  loading.value = true
  emit('load-start')

  // 重置搜索和展开状态
  searchKeyword.value = ''
  expandedKeys.value = []
  isSearchMode.value = false
  searchResults.value = []
  rootNodes.value = []

  // 重新加载根节点
  loadRootNodes()

  // 触发刷新事件
  setTimeout(() => {
    emit('refresh')
  }, 300)
}

// 监听modelValue变化，高亮对应节点
watch(
  () => props.modelValue,
  (newValue) => {
    if (newValue && treeRef.value) {
      nextTick(() => {
        // 尝试设置当前选中节点
        try {
          treeRef.value.setCurrentKey(newValue)
        } catch (error) {
          console.warn('无法设置当前节点:', error)
        }
      })
    }
  }
)

// 组件挂载时初始化根节点
onMounted(() => {
  // loadRootNodes()
})
</script>

<style scoped>
.org-tree-container {
  display: flex;
  flex-direction: column;
  height: 100%;
  overflow: hidden;
}

.search-box {
  padding: 12px;
}

.tree-content {
  flex: 1;
  overflow: auto;
}

.tree-footer {
  padding: 12px;
  text-align: right;
}

.tree-node {
  display: flex;
  gap: 4px;
  align-items: center;
}

.external-icon {
  color: #409eff;
}

.node-label {
  flex: 1;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

:deep(.el-tree-node__content) {
  padding: 8px 0;
}

:deep(.el-tree-node.is-current > .el-tree-node__content) {
  background-color: #ecf5ff;
}
</style>
